"""
主应用入口
"""
import asyncio
from fastapi import FastAPI, HTTPException, Depends, Request, WebSocket, WebSocketDisconnect, Query, Body
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from pathlib import Path
import time
import uvicorn
from starlette.requests import Request
import os
import sys
import json
from datetime import datetime
from typing import Optional, List, Dict, Any

from utils.mcp_manager import MCPManager
from models.schemas import QueryRequest, QueryResponse, Message
from utils.logger import setup_logger, get_default_logger
from utils.conversation_manager import ConversationManager

# 设置日志
logger = get_default_logger()

# 创建FastAPI应用
app = FastAPI(title="MCP助手", description="基于大模型的MCP助手，帮助理解用户意图并调用相应工具")

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 创建模板和静态文件目录
templates_dir = Path(__file__).parent / "templates"
static_dir = Path(__file__).parent / "static"

# 确保目录存在
templates_dir.mkdir(exist_ok=True)
static_dir.mkdir(exist_ok=True)

# 设置模板
templates = Jinja2Templates(directory=str(templates_dir))

# 设置静态文件
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")

# 全局MCP管理器
mcp_manager = MCPManager()

# 请求日志中间件
@app.middleware("http")
async def log_requests(request: Request, call_next):
    """记录所有HTTP请求"""
    request_id = id(request)
    start_time = time.time()
    
    logger.info(f"请求开始 [{request_id}] {request.method} {request.url.path}")
    
    try:
        response = await call_next(request)
        process_time = time.time() - start_time
        logger.info(
            f"请求完成 [{request_id}] {request.method} {request.url.path} "
            f"状态码: {response.status_code} 耗时: {process_time:.4f}秒"
        )
        return response
    except Exception as e:
        process_time = time.time() - start_time
        logger.error(
            f"请求异常 [{request_id}] {request.method} {request.url.path} "
            f"耗时: {process_time:.4f}秒 错误: {str(e)}"
        )
        raise

@app.on_event("startup")
async def startup_event():
    """应用启动时连接MCP服务器"""
    logger.info("应用启动，连接MCP服务器")
    await mcp_manager.connect_all()
    logger.info("MCP服务器连接完成")

@app.on_event("shutdown")
async def shutdown_event():
    """应用关闭时清理连接"""
    logger.info("应用关闭，清理MCP连接")
    await mcp_manager.cleanup()
    logger.info("MCP连接清理完成")

@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
    """主页"""
    logger.info("访问主页")
    servers = mcp_manager.get_servers_info()
    logger.debug(f"返回 {len(servers)} 个服务器信息到主页")
    return templates.TemplateResponse(
        "index.html", 
        {"request": request, "servers": servers}
    )

@app.get("/api/servers")
async def get_servers():
    """获取可用服务器列表"""
    logger.info("API请求: 获取服务器列表")
    servers = mcp_manager.get_servers_info()
    logger.debug(f"返回 {len(servers)} 个服务器信息")
    return {"servers": servers}

@app.post("/api/query", response_model=QueryResponse)
async def process_query(request: QueryRequest):
    """处理用户查询"""
    if not request.query:
        logger.warning("API请求: 处理查询 - 空查询")
        raise HTTPException(status_code=400, detail="查询内容不能为空")
    
    logger.info(f"API请求: 处理查询 - '{request.query}'")
    conversation_id = request.conversation_id
    if conversation_id:
        logger.debug(f"使用对话ID: {conversation_id}")
    
    try:
        logger.debug("开始处理查询")
        result = await mcp_manager.process_query(request.query, conversation_id)
        logger.info("查询处理完成")
        return QueryResponse(
            success=True,
            data=result,
            conversation_id=result.get("conversation_id")
        )
    except Exception as e:
        logger.error(f"处理查询时出错: {str(e)}", exc_info=True)
        return QueryResponse(
            success=False,
            error=str(e),
            conversation_id=conversation_id
        )

@app.get("/conversations")
def get_conversations():
    """获取所有对话ID和简要信息"""
    logger.info("获取对话列表请求")
    conversations = mcp_manager.conversation_manager.list_conversations()
    return {"conversations": conversations}

@app.get("/conversations/{conversation_id}")
def get_conversation(conversation_id: str):
    """获取指定对话的详细信息和消息历史"""
    logger.info(f"获取对话信息请求: {conversation_id}")
    messages = mcp_manager.conversation_manager.get_messages(conversation_id)
    server_id = mcp_manager.conversation_manager.get_server_id(conversation_id)
    
    if not messages:
        raise HTTPException(status_code=404, detail="对话不存在")
    
    return {
        "conversation_id": conversation_id,
        "server_id": server_id,
        "messages": messages
    }

@app.delete("/conversations/{conversation_id}")
def delete_conversation(conversation_id: str):
    """删除指定的对话"""
    logger.info(f"删除对话请求: {conversation_id}")
    success = mcp_manager.conversation_manager.delete_conversation(conversation_id)
    
    if not success:
        raise HTTPException(status_code=404, detail="对话不存在")
    
    return {"success": True, "message": "对话已删除"}

@app.get("/current-time")
def get_current_time():
    """获取服务器当前时间信息"""
    now = datetime.now()
    
    # 中英文星期对照
    weekday_cn = {
        0: "一",
        1: "二",
        2: "三",
        3: "四",
        4: "五", 
        5: "六",
        6: "日"
    }
    
    weekday_en = now.strftime("%A")
    weekday_cn_str = weekday_cn[now.weekday()]
    
    # 生成时间相关的上下文信息
    yesterday = now - datetime.timedelta(days=1)
    tomorrow = now + datetime.timedelta(days=1)
    last_week = now - datetime.timedelta(weeks=1)
    next_week = now + datetime.timedelta(weeks=1)
    next_month = now.replace(month=now.month+1 if now.month < 12 else 1, year=now.year if now.month < 12 else now.year+1)
    last_month = now.replace(month=now.month-1 if now.month > 1 else 12, year=now.year if now.month > 1 else now.year-1)
    
    # 计算季度信息
    current_quarter = (now.month - 1) // 3 + 1
    quarter_start_month = (current_quarter - 1) * 3 + 1
    quarter_start = now.replace(month=quarter_start_month, day=1)
    
    return {
        "timestamp": int(now.timestamp()),
        "iso": now.isoformat(),
        "formatted": now.strftime("%Y年%m月%d日 %H:%M:%S"),
        "year": now.year,
        "month": now.month,
        "day": now.day,
        "hour": now.hour,
        "minute": now.minute,
        "second": now.second,
        "weekday": {
            "en": weekday_en,
            "cn": weekday_cn_str,
            "number": now.weekday()
        },
        "context": {
            "yesterday": {
                "date": yesterday.strftime("%Y-%m-%d"),
                "formatted": yesterday.strftime("%Y年%m月%d日"),
                "weekday": weekday_cn[yesterday.weekday()]
            },
            "tomorrow": {
                "date": tomorrow.strftime("%Y-%m-%d"),
                "formatted": tomorrow.strftime("%Y年%m月%d日"),
                "weekday": weekday_cn[tomorrow.weekday()]
            },
            "last_week": {
                "date": last_week.strftime("%Y-%m-%d"),
                "formatted": last_week.strftime("%Y年%m月%d日")
            },
            "next_week": {
                "date": next_week.strftime("%Y-%m-%d"),
                "formatted": next_week.strftime("%Y年%m月%d日")
            },
            "last_month": {
                "year": last_month.year,
                "month": last_month.month,
                "formatted": last_month.strftime("%Y年%m月")
            },
            "next_month": {
                "year": next_month.year,
                "month": next_month.month,
                "formatted": next_month.strftime("%Y年%m月")
            },
            "quarter": {
                "current": current_quarter,
                "start_month": quarter_start_month,
                "start_date": quarter_start.strftime("%Y-%m-%d"),
                "formatted": f"{now.year}年第{current_quarter}季度"
            }
        },
        "description": {
            "cn": f"当前时间是{now.strftime('%Y年%m月%d日 %H:%M:%S')}，星期{weekday_cn_str}",
            "en": f"Current time is {now.strftime('%Y-%m-%d %H:%M:%S')}, {weekday_en}"
        }
    }

if __name__ == "__main__":
    uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)